package com.example.thirdannotation.y2022.annotation.valid;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;

/**
 * @author: dangwen
 * @createDate: 2020/10/2
 * ConstraintValidator<ListValue,Integer>泛型需要传入两个值：第一个是注解，第二个是注解的返回类型
 */
public class IntValuesConstraintValidator implements ConstraintValidator<IntValues,Integer> {

    /**
     * 推荐在类中将不需要重新赋值的集合使用 final 修饰符，以提高代码的健壮性和可靠性。
     * 1. 线程安全性：通过将集合设置为 final，可以避免多线程环境下的并发修改问题。在多线程环境中，如果集合被重新赋值，可能会导致不可预期的结果或者竞态条件。
     * 2. 代码可读性：final 可以传达一种语义意义，即在初始化后，该集合引用不会再指向其他对象。这样可以更清晰地表达代码的意图，让其他开发人员更容易理解和维护代码。
     * 3. 编译时检查：使用 final 可以在编译时强制对集合的初始化进行检查，避免在后续代码中意外地对集合进行重新赋值，增加代码的稳定性和可靠性。
     */
    private final Set<Integer> set = new HashSet<>();

    /**
     * 初始化方法：会在初始化完成后，拿到IntValues中定义的值
     */
    @Override
    public void initialize(IntValues constraintAnnotation) {
        int[] values = constraintAnnotation.values();
        if(values.length > 0){
            for (int value : values) {
                set.add(value);
            }
        }
    }

    /**
     * 校验函数：
     * @param integer 用户输入的value
     * @param constraintValidatorContext
     * @return
     */
    @Override
    public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
        return set.contains(integer);
    }
}
